package ph.com.gs3.formalistics.managers;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;

import ph.com.gs3.formalistics.communicators.CommunicatorModule.CommunicatorException;
import ph.com.gs3.formalistics.communicators.FormCommunicatorModule;
import ph.com.gs3.formalistics.model.dao.ConfigDAO;
import ph.com.gs3.formalistics.model.dao.FormsDAO;
import ph.com.gs3.formalistics.model.valueobjects.application.APIResponse;
import ph.com.gs3.formalistics.model.valueobjects.application.APIResponse.APIInvalidResponseException;
import ph.com.gs3.formalistics.model.valueobjects.application.Form;
import ph.com.gs3.formalistics.model.valueobjects.application.Form.InvalidFormException;
import ph.com.gs3.formalistics.model.valueobjects.application.FormField.InvalidFormFieldException;
import ph.com.gs3.formalistics.utilities.FLLogger;
import ph.com.gs3.formalistics.utilities.FLLogger.LogType;
import android.annotation.SuppressLint;
import android.database.SQLException;

public class FormManager {

	public static final String TAG = FormManager.class.getSimpleName();

	private ConfigDAO configDAO;
	private FormsDAO formsDAO;
	private FormCommunicatorModule formCommModule;

	public FormManager(ConfigDAO configDAO, FormsDAO formsDAO, FormCommunicatorModule formCommModule) {
		this.configDAO = configDAO;
		this.formsDAO = formsDAO;
		this.formCommModule = formCommModule;
	}

	@SuppressLint("SimpleDateFormat")
	public List<Form> updateForms() throws CommunicatorException {

		List<Form> forms = new ArrayList<Form>();

		APIResponse downloadResponse;

		// get updates starting from today's date
		try {

			formsDAO.open();

			// if there are forms existing in the database, add a filter by last
			// update, otherwise, don't put filter
			if (formsDAO.getFormCount(formCommModule.getServer()) > 0) {
				String lastFormsUpdate = configDAO.getLastFormsUpdate();

				FLLogger.d(TAG, "Updating forms starting from: " + lastFormsUpdate);
				downloadResponse = formCommModule.downloadFormUpdates(lastFormsUpdate);
			} else {
				downloadResponse = formCommModule.downloadFormUpdates(null);
			}

			if (downloadResponse.operationSuccessful()) {

				String resultsRaw = downloadResponse.getResults();
				// throws JSONException
				JSONArray results = new JSONArray(resultsRaw);

				for (int i = 0; i < results.length(); i++) {

					// throws InvalidFormException
					Form form = Form.createFromJSON(results.getJSONObject(i),
					        formCommModule.getServer());

					try {
						forms.add(formsDAO.saveForm(form));
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InvalidFormFieldException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

				// update the last form update in the config
				configDAO.setLastFormsUpdate(downloadResponse.getServerDate());

				return forms;

			} else {
				FLLogger.log(TAG, LogType.ERROR,
				        "Error downloading forms: " + downloadResponse.getErrorMessage());
				throw new CommunicatorException(downloadResponse.getErrorMessage());
			}

		} catch (APIInvalidResponseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidFormException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			formsDAO.close();
		}

		// TODO, throw exceptions later
		return null;

	}

}
